﻿#include <QFile>
#include <QTimer>
#include <QDebug>
#include <QDir>
#include <QMessageBox>
#include <QDateTime>
#include "CLogWidget.h"
#include "CLogMng.h"
#include "Public.h"
#include "CLogDetails.h"
#include "CLogHisDlg.h"
#include "CLogCfgDlg.h"

CLogWidget::CLogWidget(const QString& moduleName, const QVector<QString>& vecDeviceNames,int nType, QWidget *parent)
	: QWidget(parent)
	, m_sModuleName(moduleName)
	, m_vecDeviceNames(vecDeviceNames)
	, m_nMaxDisplayCount(100)
	, m_nType(nType)
	, m_bFiltering(false)
{
	ui.setupUi(this);
	initConnect();
	initUI();
	initModel();
	// 应用XML配置
	applyConfig();
	initContextMenu();  // 初始化右键菜单
	// 延迟加载最近50条历史日志（避免界面卡顿）
	QTimer::singleShot(1000, this, &CLogWidget::loadRecentHistoryLogs);
}

CLogWidget::~CLogWidget()
{}

void CLogWidget::setShowLimit(int nShowLimit)
{
	m_nMaxDisplayCount = nShowLimit;
}

void CLogWidget::refreshConfig()
{
	// 清空当前显示
	clearLogs();
	// 重新应用配置
	applyConfig();
	// 重新加载最近的历史日志
	QTimer::singleShot(500, this, &CLogWidget::loadRecentHistoryLogs);
}

void CLogWidget::addLog(const QSharedPointer<LogData>& logData)
{
	// 检查是否属于本控件显示的日志
	if (!isLogBelongsToWidget(logData))
	{
		return;
	}

	if (m_bFiltering) //如果正在筛选，直接返回
	{
		return;
	}

	//判断是否符合筛选的标准
	// 关键词筛选
	QString sKey = ui.lineEditKey->text();
	QString sDevName = ui.comboBoxDevice->currentText();
	QString sLevel = ui.comboBoxLevel->currentText();
	if (sKey !="*")
	{
		if (!logData->sLogContent.contains(sKey, Qt::CaseInsensitive) &&
			!logData->sFuncName.contains(sKey, Qt::CaseInsensitive))
		{
			return;
		}
	}
	// 设备筛选
	if (ui.comboBoxDevice->currentText()!="*") 
	{
		if (logData->sDeviceName != sDevName)
		{
			return;
		}
	}
	// 级别筛选
	if (ui.comboBoxLevel->currentText() != "*")
	{
		if (logData->sLevel != sLevel)
		{
			return;
		}
	}

	// 创建行数据
	QList<QStandardItem*> items = createLogRowItems(logData);
	if (items.isEmpty())
	{
		return;
	}

	CLogMng& logMng = CLogMng::instance();

	// 根据显示顺序插入
	if (logMng.m_showDescend)
	{
		// 倒序：插入到第一行（最新日志显示在最上面）
		m_pModel->insertRow(0, items);
	}
	else
	{
		// 正序：追加到最后
		m_pModel->appendRow(items);
	}

	// 限制显示条数（只有在启用限制时才限制）
	if (m_nMaxDisplayCount > 0 && m_pModel->rowCount() > m_nMaxDisplayCount)
	{
		if (logMng.m_showDescend)
		{
			// 倒序时删除最后一行（最旧的）
			m_pModel->removeRow(m_nMaxDisplayCount);
		}
		else
		{
			// 正序时删除第一行（最旧的）
			m_pModel->removeRow(0);
		}
	}

	// 刷新所有行的序号
	refreshRowNumbers();

	// 自动滚动
	if (logMng.m_showDescend)
	{
		ui.tableView->scrollToTop();
	}
	else
	{
		ui.tableView->scrollToBottom();
	}
}

void CLogWidget::clearLogs()
{
	m_pModel->removeRows(0, m_pModel->rowCount());
}

void CLogWidget::applyConfig()
{
	CLogMng& logMng = CLogMng::instance();

	// 1. 设置显示条数限制
	if (logMng.m_isShowLimit)
	{
		m_nMaxDisplayCount = logMng.m_showLimit;
	}
	else 
	{
		m_nMaxDisplayCount = -1; // 无限制
	}

	// 2. 应用表格样式
	QString styleSheet = QString(
		"#LogWidget_Main { "
		"background-color: %1; "
		"}"
		"#LogWidget_TableView { "
		"background-color: %1; "
		"gridline-color: %2; "
		"alternate-background-color: %3; "
		"border: 1px solid %2; "
		"}"
		"#LogWidget_TableView::section { "
		"background-color: #f0f0f0; "
		"padding: 4px; "
		"border: 1px solid %2; "
		"font-weight: bold; "
		"}"
		"#LogWidget_TabWidget::pane { "
		"border: 1px solid %2; "
		"background-color: %1; "
		"}"
		"#LogWidget_FilterButton { "
		"background-color: #e0e0e0; "
		"border: 1px solid %2; "
		"border-radius: 4px; "
		"padding: 5px 10px; "
		"}"
		// ... 其他组件样式
	).arg(logMng.m_tableBackColor.name())
		.arg(logMng.m_tableGridColor.name())
		.arg(logMng.m_tableBackColor.lighter(110).name());

	ui.tableView->setStyleSheet(styleSheet);
}

void CLogWidget::refreshRowNumbers()
{
	int rowCount = m_pModel->rowCount();

	if (CLogMng::instance().m_showDescend)
	{
		// 倒序显示：最上面的行序号最大（最新），从当前总行数开始递减
		for (int i = 0; i < rowCount; ++i)
		{
			QStandardItem* item = m_pModel->item(i, 0);
			if (item)
			{
				item->setText(QString::number(rowCount - i));
			}
		}
	}
	else
	{
		// 正序显示：最上面的行序号最小（最旧），从1开始递增
		for (int i = 0; i < rowCount; ++i)
		{
			QStandardItem* item = m_pModel->item(i, 0);
			if (item)
			{
				item->setText(QString::number(i + 1));
			}
		}
	}
}

void CLogWidget::addLogsBatch(const QVector<QSharedPointer<LogData>>& logs)
{
	if (logs.isEmpty()) 
	{
		return;
	}

	CLogMng& logMng = CLogMng::instance();
	bool showDescend = logMng.m_showDescend; // 缓存配置值
	// 预先计算限制
	bool needLimit = (m_nMaxDisplayCount > 0);
	int currentRowCount = m_pModel->rowCount();
	// 根据显示顺序处理日志
	if (showDescend)
	{
		// 倒序显示：最新的在最上面
		for (const auto& logData : logs) 
		{
			addSingleLog(logData);
			// 如果达到显示限制，就停止
			if (needLimit && m_pModel->rowCount() >= m_nMaxDisplayCount)
			{
				break;
			}
		}
		ui.tableView->scrollToTop();
	}
	else 
	{
		// 正序显示：最旧的在最上面
		for (auto it = logs.rbegin(); it != logs.rend(); ++it) 
		{
			addSingleLog(*it);
			// 如果达到显示限制，就停止
			if (needLimit && m_pModel->rowCount() >= m_nMaxDisplayCount)
			{
				break;
			}
		}
		ui.tableView->scrollToBottom();
	}
	// 刷新所有行的序号
	refreshRowNumbers();
}

void CLogWidget::addSingleLog(const QSharedPointer<LogData>& logData)
{
	QList<QStandardItem*> items = createLogRowItems(logData);
	if (!items.isEmpty())
	{
		m_pModel->appendRow(items);
	}
}

QList<QStandardItem*> CLogWidget::createLogRowItems(const QSharedPointer<LogData>& logData)
{
	QList<QStandardItem*> items;

	// 获取日志等级配置
	CLogMng& logMng = CLogMng::instance();
	SLogLevelConfig levelConfig = logMng.getLogLevelConfig(logData->nLevel);

	// 根据级别设置颜色
	QBrush fontColor(levelConfig.textColor);
	QBrush backColor(levelConfig.backColor);

	// 序号 - 先设置为空，后面统一刷新
	QStandardItem* itemNo = new QStandardItem("");
	itemNo->setForeground(fontColor);
	itemNo->setBackground(backColor);
	itemNo->setTextAlignment(Qt::AlignCenter);
	items.append(itemNo);

	// 级别
	QStandardItem* itemLevel = new QStandardItem(logData->sLevel);

	// 设置图标
	if (!levelConfig.iconPath.isEmpty())
	{
		QIcon icon(levelConfig.iconPath);
		if (!icon.isNull()) {
			itemLevel->setIcon(icon);
		}
		else {
			qWarning() << "Failed to load icon:" << levelConfig.iconPath;
		}
	}

	itemLevel->setForeground(fontColor);
	itemLevel->setBackground(backColor);
	itemLevel->setTextAlignment(Qt::AlignCenter);
	items.append(itemLevel);

	// 设备
	QStandardItem* itemDevice = new QStandardItem(logData->sDeviceName);
	itemDevice->setForeground(fontColor);
	itemDevice->setBackground(backColor);
	itemDevice->setTextAlignment(Qt::AlignCenter);
	items.append(itemDevice);

	// 时间
	QStandardItem* itemTime = new QStandardItem(logData->sTime);
	itemTime->setForeground(fontColor);
	itemTime->setBackground(backColor);
	itemTime->setTextAlignment(Qt::AlignCenter);
	items.append(itemTime);

	// 模块
	QStandardItem* itemModule = new QStandardItem(logData->sFuncName);
	itemModule->setForeground(fontColor);
	itemModule->setBackground(backColor);
	itemModule->setTextAlignment(Qt::AlignCenter);
	items.append(itemModule);

	// 内容
	QStandardItem* itemContent = new QStandardItem(logData->sLogContent);
	itemContent->setForeground(fontColor);
	itemContent->setBackground(backColor);
	itemContent->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
	items.append(itemContent);

	return items;
}

bool CLogWidget::isLogBelongsToWidget(const QSharedPointer<LogData>& logData) const
{
	// 检查模块名是否匹配
	if (logData->sModuleName != m_sModuleName) 
	{
		return false;
	}
	if (m_nType == 0)//需要严格匹配设备
	{
		bool bFind = false;
		for (int i = 0; i < m_vecDeviceNames.size(); i++)
		{
			if (logData->sDeviceName == m_vecDeviceNames[i])
			{
				bFind = true;
				break;
			}
		}
		if (!bFind)
		{
			return false;
		}
	}
	// 检查设备名是否在设备列表中
	return m_vecDeviceNames.contains(logData->sDeviceName);
}

void CLogWidget::initConnect()
{
	connect(ui.pushButtonFilter, &QPushButton::clicked, this, &CLogWidget::slotPushFilter);
	connect(ui.tableView, &QTableView::doubleClicked, this, &CLogWidget::slotDoubleClick);
}

void CLogWidget::initUI()
{
	// 为所有组件设置唯一的对象名称
	this->setObjectName("LogWidget_Main");
	ui.tableView->setObjectName("LogWidget_TableView");
	ui.pushButtonFilter->setObjectName("LogWidget_FilterButton");
	ui.comboBoxDevice->setObjectName("LogWidget_DeviceCombo");
	ui.comboBoxLevel->setObjectName("LogWidget_LevelCombo");
	ui.lineEditKey->setObjectName("LogWidget_KeyEdit");

	ui.labelName->setText(m_sModuleName);
	ui.comboBoxLevel->addItem("*");
	ui.comboBoxDevice->addItem("*");
	for (auto itor = CLogMng::instance().m_mapLogLevelConfigs.begin(); itor != CLogMng::instance().m_mapLogLevelConfigs.end(); itor++)
	{
		QPixmap pixmap(itor.value().iconPath);
		ui.comboBoxLevel->addItem(QIcon(pixmap),itor.value().desc);
	}
	if (m_nType == 0)
	{
		for (int i = 0; i < m_vecDeviceNames.size(); i++)
		{
			ui.comboBoxDevice->addItem(m_vecDeviceNames[i]);
		}
	}
	else if(m_nType == 1)
	{
		QString sPath = QCoreApplication::applicationDirPath() + "/Log/" + m_sModuleName;
		QDir dir(sPath);
		if (dir.exists()) 
		{
			// 设置过滤器：只获取目录，不获取文件
			dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
			// 获取所有目录名称
			QStringList folderNames = dir.entryList();
			ui.comboBoxDevice->addItems(folderNames);
			m_vecDeviceNames = folderNames.toVector();
		}
	}

	//更多
	QMenu* pMenu = new QMenu(this);
	QAction* pConfig = new QAction(QIcon(":/icon/Config1.png"), QString::fromLocal8Bit("配置"));
	QAction* pHis = new QAction(QIcon(":/icon/History1.png"), QString::fromLocal8Bit("历史日志"));
	pMenu->addAction(pConfig);
	pMenu->addAction(pHis);
	ui.toolButtonMore->setMenu(pMenu);
	ui.toolButtonMore->setPopupMode(QToolButton::InstantPopup);
	connect(pConfig, &QAction::triggered, this, &CLogWidget::slotConfig);
	connect(pHis, &QAction::triggered, this, &CLogWidget::slotHis);

	//表格相关
	ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
	ui.tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
	ui.tableView->setAlternatingRowColors(true);
	ui.tableView->verticalHeader()->setVisible(false);
	ui.tableView->horizontalHeader()->setStretchLastSection(true);
}

void CLogWidget::initModel()
{
	m_pModel = new QStandardItemModel(this);
	m_pModel->setColumnCount(6);
	QStringList headers;
	headers << QString::fromLocal8Bit("序号")
		<< QString::fromLocal8Bit("级别")
		<< QString::fromLocal8Bit("设备")
		<< QString::fromLocal8Bit("时间")
		<< QString::fromLocal8Bit("模块")
		<< QString::fromLocal8Bit("内容");
	m_pModel->setHorizontalHeaderLabels(headers);

	ui.tableView->setModel(m_pModel);

	// 设置列宽
	ui.tableView->setColumnWidth(0, 50);   // 序号
	ui.tableView->setColumnWidth(1, 100);   // 级别
	ui.tableView->setColumnWidth(2, 150);  // 设备
	ui.tableView->setColumnWidth(3, 140);  // 时间
	ui.tableView->setColumnWidth(4, 100);   // 模块
	// 内容列自动拉伸
}

void CLogWidget::initContextMenu()
{
	m_pContextMenu = new QMenu(this);

	QAction* actionClear = new QAction(QIcon(":/icon/clear.png"), QString::fromLocal8Bit("清空列表"), this);
	connect(actionClear, &QAction::triggered, this, &CLogWidget::slotClearList);

	m_pContextMenu->addAction(actionClear);

	// 设置表格支持右键菜单
	ui.tableView->setContextMenuPolicy(Qt::CustomContextMenu);
	connect(ui.tableView, &QTableView::customContextMenuRequested, this, &CLogWidget::slotShowContextMenu);
}

void CLogWidget::onLogAdded(const QSharedPointer<LogData>& logData)
{
	addLog(logData);
}

void CLogWidget::onConfig()
{
	refreshConfig();
}

void CLogWidget::loadRecentHistoryLogs()
{
	CLogMng& logMng = CLogMng::instance();
	try
	{
		// 收集所有设备的日志
		QVector<QSharedPointer<LogData>> allRecentLogs;

		// 为每个设备加载最近50条日志
		for (const QString& deviceName : m_vecDeviceNames)
		{
			int loadCount = 50;
			QVector<QSharedPointer<LogData>> recentLogs = getRecentHistoryLogs(m_sModuleName, deviceName, loadCount);

			if (!recentLogs.isEmpty())
			{
				allRecentLogs.append(recentLogs);
			}
		}

		if (allRecentLogs.isEmpty())
		{
			qDebug() << "No recent history logs found for module:" << m_sModuleName;
			return;
		}

		// 总体按时间排序（最新的在前面）
		std::sort(allRecentLogs.begin(), allRecentLogs.end(),
			[](const QSharedPointer<LogData>& a, const QSharedPointer<LogData>& b) {
			QDateTime timeA = QDateTime::fromString(a->sTime, "yyyy-MM-dd hh:mm:ss");
			QDateTime timeB = QDateTime::fromString(b->sTime, "yyyy-MM-dd hh:mm:ss");
			return timeA > timeB; // 降序排列，最新的在前
		});

		// 限制总显示条数
		if (allRecentLogs.size() > m_nMaxDisplayCount && m_nMaxDisplayCount > 0) {
			allRecentLogs.resize(m_nMaxDisplayCount);
		}

		// 批量添加排序后的日志
		addLogsBatch(allRecentLogs);
	}
	catch (const std::exception& e)
	{
		qCritical() << "Failed to load recent history logs for module:"
			<< m_sModuleName << ":" << e.what();
	}
}

void CLogWidget::slotPushFilter()
{
	QString sKey = ui.lineEditKey->text();
	QString sDeviceName = ui.comboBoxDevice->currentText();
	QString sLevel = ui.comboBoxLevel->currentText();

	// 检查是否是清空筛选条件
	if (sKey.isEmpty() && sDeviceName == "*" && sLevel == "*")
	{
		// 清空筛选，恢复正常显示
		m_bFiltering = false;
		refreshConfig();
		return;
	}

	// 设置筛选状态
	m_bFiltering = true;

	// 使用定时器延迟执行，避免界面卡顿
	QTimer::singleShot(50, [this, sKey, sDeviceName, sLevel]()
	{
		try 
		{
			// 清空当前显示
			clearLogs();

			// 从文件查询符合条件的日志（只查询当天，最多100条）
			QVector<QSharedPointer<LogData>> filteredLogs = queryTodayLogsWithFilter(sKey, sDeviceName, sLevel);
			if (filteredLogs.size())
			{
				// 批量添加筛选结果
				addLogsBatch(filteredLogs);

				// 滚动到最新日志
				if (CLogMng::instance().m_showDescend)
				{
					ui.tableView->scrollToTop();
				}
				else 
				{
					ui.tableView->scrollToBottom();
				}
			}
			m_bFiltering = false;
		}
		catch (const std::exception& e)
		{
			qCritical() << "Filter logs failed:" << e.what();
			m_bFiltering = false;
		}
	});
}

void CLogWidget::slotClearList()
{
	clearLogs();
}

void CLogWidget::slotShowContextMenu(const QPoint& pos)
{
	if (m_pContextMenu)
	{
		m_pContextMenu->exec(ui.tableView->viewport()->mapToGlobal(pos));
	}
}

void CLogWidget::slotDoubleClick()
{
	int nRow = ui.tableView->currentIndex().row();
	CLogDetails oper;
	QString sLevel = m_pModel->item(nRow, 1)->text();
	QString sDeviceName = m_pModel->item(nRow, 2)->text();
	QString sTime = m_pModel->item(nRow, 3)->text();
	QString sFuncName = m_pModel->item(nRow, 4)->text();
	QString sLog = m_pModel->item(nRow, 5)->text();
	oper.setDate(sDeviceName, sTime, sFuncName,sLevel, sLog);
	oper.exec();
}

void CLogWidget::slotConfig()
{
	CLogCfgDlg oper;
	oper.exec();
}

void CLogWidget::slotHis()
{
	CLogHisDlg oper(m_sModuleName, m_vecDeviceNames, m_nType);
	oper.exec();
}

QVector<QSharedPointer<LogData>> CLogWidget::queryTodayLogsWithFilter(const QString& keyword,const QString& deviceName,const QString& levelDesc)
{
	QVector<QSharedPointer<LogData>> resultLogs;
	resultLogs.reserve(100); // 预分配内存
	CLogMng& logMng = CLogMng::instance();

	// 确定要查询的设备列表
	QVector<QString> queryDevices;
	if (deviceName == "*" || deviceName.isEmpty())
	{
		queryDevices = m_vecDeviceNames;//查询全部
	}
	else 
	{
		// 查询指定设备
		queryDevices.append(deviceName);
	}

	// 转换级别描述为级别值
	int levelFilter = -1;
	if (levelDesc != "*" && !levelDesc.isEmpty()) 
	{
		levelFilter = getLevelFromString(levelDesc);
	}

	// 获取当天日期
	QString today = QDateTime::currentDateTime().toString("yyyyMMdd");

	// 为每个设备查询当天的日志
	// 构建当天日志文件路径
	QString appDir = QCoreApplication::applicationDirPath();
	QString year = QDateTime::currentDateTime().toString("yyyy");
	QString month = QDateTime::currentDateTime().toString("yyyyMM");
	for (const QString& device : queryDevices) 
	{
		// 如果已经找到100条，就停止查询
		if (resultLogs.size() >= 100) 
		{
			break;
		}
		QString logDir = QString("%1/Log/%2/%3/%4/%5/")
			.arg(appDir)
			.arg(m_sModuleName)
			.arg(device)
			.arg(year)
			.arg(month);

		QString fileName = QString("%1%2.log").arg(device).arg(today);
		QString filePath = QDir(logDir).absoluteFilePath(fileName);

		// 如果日志文件不存在，跳过
		if (!QFile::exists(filePath)) 
		{
			continue;
		}

		// 读取当天日志文件并筛选
		QVector<QSharedPointer<LogData>> deviceLogs = readAndFilterLogFile(filePath, m_sModuleName, device, keyword, levelFilter);

		// 添加到结果中
		for (const auto& logData : deviceLogs)
		{
			resultLogs.append(logData);

			// 如果达到100条，就停止
			if (resultLogs.size() >= 100) 
			{
				break;
			}
		}
	}

	// 按时间排序（最新的在前面）
	std::sort(resultLogs.begin(), resultLogs.end(),
		[](const QSharedPointer<LogData>& a, const QSharedPointer<LogData>& b) {
		QDateTime timeA = QDateTime::fromString(a->sTime, "yyyy-MM-dd hh:mm:ss");
		QDateTime timeB = QDateTime::fromString(b->sTime, "yyyy-MM-dd hh:mm:ss");
		return timeA > timeB; // 降序排列
	});

	// 确保不超过100条
	if (resultLogs.size() > 100)
	{
		resultLogs.resize(100);
	}

	return resultLogs;
}

QVector<QSharedPointer<LogData>> CLogWidget::readAndFilterLogFile(const QString& filePath,const QString& moduleName,const QString& deviceName,const QString& keyword,int levelFilter) const
{
	QVector<QSharedPointer<LogData>> filteredLogs;
	filteredLogs.reserve(100);

	QFile file(filePath);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		return filteredLogs;
	}

	QTextStream stream(&file);
	stream.setCodec("UTF-8");

	// 从文件末尾开始读取（获取最新的日志）
	QStringList allLines;
	while (!stream.atEnd()) 
	{
		allLines.append(stream.readLine());
	}
	file.close();

	//从最新的日志开始检查（文件末尾）
	int count = 0;
	for (int i = allLines.size() - 1; i >= 0 && count < 100; --i)
	{
		QString line = allLines[i].trimmed();
		if (line.isEmpty()) 
		{
			continue;
		}

		// 解析日志行
		QSharedPointer<LogData> logData = parseLogLine(line, moduleName, deviceName);
		if (!logData)
		{
			continue;
		}

		// 应用筛选条件
		bool match = true;

		// 关键词筛选
		if (!keyword.isEmpty())
		{
			if (!logData->sLogContent.contains(keyword, Qt::CaseInsensitive) &&
				!logData->sFuncName.contains(keyword, Qt::CaseInsensitive))
			{
				match = false;
			}
		}

		// 级别筛选
		if (levelFilter >= 0 && logData->nLevel != levelFilter) {
			match = false;
		}

		if (match) 
		{
			filteredLogs.append(logData);
			count++;
		}
	}

	return filteredLogs;
}
